www.gusucode.com > XerCMS 携云PHP企业建站程序 v2015PHP源码程序 > XerCMS 携云PHP企业建站程序 v2015/XerCMS_v20150724/XerCMS_v20150724/XerCMS/Library/XerCMS_mail.php
<?php /** * PHBMail - PHBMail.php * @version: 1.5.0 * @date: 2009-08-18 * @desc: PHBMail SMTP邮件发送类 for PHP5 * @author: 银魂 <xwsoul@gmail.com> * @copyright: Copyright (c) 2007-2009 PHBChina * @link:http://code.google.com/p/phbchina/ */ !defined('XERCMS') && exit('Access Denied'); class MAIL { //smtp主机地址 protected $host; //用户名 protected $user; //密码 protected $psw; //主机端口 protected $port=25; //主机端口 protected $timeout; //发件人地址 protected $from; //发件人昵称 protected $sender; //是否允许SSL protected $enableSSL=false; //是否允许调试 protected $debug=false; //普通收件人地址 protected $to; protected $toStr; //抄送收件人地址 protected $cc; protected $ccStr; //可以发送否(发件确认) protected $bcc; protected $couldSend=false; //信件标题 protected $subject; //信件内容 protected $content; //命令确认符 protected $CRLF; //邮件等级 h - high n - normal l - low protected $priority='n'; //HTML支持 public $HTMLsupport=true; //字符集 public $charset='utf-8'; //是否需要回执 protected $returnReceipt=false; //是否开启64进制转换 protected $ifBaseChar = true; //附件,字符串 protected $attachment=array(); //错误号 public $errno; //错误描述 public $error; //错误的收件人 protected $errorAddr; //错误步骤 protected $step; //SMTP链接 protected $fp = null; /** * 构造 */ public function __construct($host,$user,$psw,$port=25,$CRLF="\n", $timeout=1) { $this->host = $host; $this->port = $port; $this->user = $user; $this->psw = $psw; $this->CRLF = $CRLF; $this->timeout = $timeout*1000000; } /** * 析构 */ public function __destruct() { $this->disconnect(); } public function enableDebug($bool) { $this->debug = $bool; } public function enableSSL($bool) { $this->enableSSL = $bool; } /** * 连接服务器 */ protected function connect() { error_reporting(1); // if ($this->enableSSL) // $this->host = 'ssl://'.$this->host; $this->fp = fsockopen($this->host, $this->port, $this->errno, $this->error, 5); error_reporting(7); if (!$this->fp) { $this->makeInfo('Server Connect !','Can not connect to the server --- ['.$this->host.']! Please check it !',403); $this->throwE(); } //设置流资源的超时时间 - 1秒!避免fgets函数操作被挂起,导致脚本超时! stream_set_timeout($this->fp,null,$this->timeout); $this->smtpInfo('Waitting for connection !',220); $this->sayHello(); if($this->fp != null) { $this->readytoLogin(); if($this->enableSSL) { $this->startTLS(); } $this->checkUser(); $this->checkPass(); return true; } else return false; } /** * 断开连接 */ protected function disconnect() { error_reporting(1); $this->smtpWrite('QUIT'); fclose($this->fp); $this->fp = null; error_reporting(7); } private function startTLS() { $this->smtpWrite('STARTTLS'); $this->smtpInfo('StartTLS',220); if($this->fp != null) { stream_socket_enable_crypto($this->fp, true,STREAM_CRYPTO_METHOD_SSLv2_CLIENT); } } /** * 向服务器打招呼 */ private function sayHello() { $this->smtpWrite('helo '.$this->host); $this->smtpInfo('Say hello',250); return true; } /** * 准备登陆 */ private function readytoLogin() { $this->smtpWrite('auth login'); $this->smtpInfo('Prepare to login',334); return true; } /** * 验证用户名 用户名会以64位编码后传送 */ private function checkUser() { $this->smtpWrite(base64_encode($this->user)); $this->smtpInfo('Check Username',334); return true; } /** * 验证密码 用户名会以64位编码后传送 */ private function checkPass() { $this->smtpWrite(base64_encode($this->psw)); $this->smtpInfo('Check user password',235); return true; } /** * 邮件发送 */ public function send($subject,$content) { $this->connect(); if($this->fp != null) { $this->subject = $subject; $this->content = $content; $this->makeFromAddr(); $this->makeToAddr(); $this->dataCommand(); $this->writeMail(); if($this->enableSSL) stream_socket_enable_crypto($this->fp, false); return true; } else return false; } /** * 收件人信息设置 */ public function setFrom($name,$addr) { $this->sender = $name; $this->from = $addr; } /** * 写信人地址确认指令 */ private function makeFromAddr() { if(!$this->sender || !$this->from) $this->throwInfo('Check the Email address of the sender !','Use PHBMail::fromer() first !',500); $this->smtpWrite('MAIL FROM:<'.$this->from.'>'); $this->smtpInfo('Check the Email address of the sender',250); return true; } /** * 收信人地址确认 */ protected function makeToAddr() { $this->to(); $this->cc(); $this->bcc(); if(!$this->couldSend) { $this->error .= $this->errorAddr; $this->throwE(); } return true; } /** * rcpt指令 */ protected function rcpt($email) { $this->smtpWrite("rcpt to: <{$email}>"); } /** * 设置普通收件人信息 * * @param array $to */ public function setTo($to=NULL) { if(!is_array($to) && empty($to)) $this->throwInfo('who do you want to send?','Error paramer',500); else $this->to = $to; } /** * 生成普通收件人信息 * */ protected function to(){ if(!$this->to) return ; foreach($this->to as $name => $email) { $this->rcpt($email); $this->smtpInfoBase('Check the Email addr of the toReceiver - '.$email); if($this->errno!==250) { $this->errorAddr .= "Bad Email address : <b>".$email."</b> !<br />\n"; } else { $this->toStr .= '"'.$this->baseChar($name).'" <'.$email.'>, '; $this->couldSend = true; } } } /** * 设置抄送人信息 * * @param arr $cc */ public function setCc($cc=NULL){ if(!is_array($cc) && empty($cc)) $this->throwInfo('who do you want to cc?','Error paramer',500); else $this->cc = $cc; } /** * 生成抄送收件人信息 * */ protected function cc(){ if(!$this->cc) return ; foreach($this->cc as $name => $email) { $this->rcpt($email); $this->smtpInfoBase('Check the Email addr of the ccReceiver - '.$email); if($this->errno!==250) { $this->errorAddr .= "Bad Email address : <b>".$email."</b> !<br />\n"; } else { $this->ccStr .= '"'.$this->baseChar($name).'" <'.$email.'>, '; $this->couldSend = true; } } } /** * 设置密送人信息 * * @param array $bcc */ public function setBcc($bcc=NULL) { if(!is_array($bcc) && empty($bcc)) $this->throwInfo('who do you want to bcc?','Error paramer',500); else $this->bcc = $bcc; } /** * 生成密送信息 * */ protected function bcc(){ if(!$this->bcc) return ; foreach($this->bcc as $email) { $this->rcpt($email); $this->smtpInfoBase('Check the Email addr of the ccReceiver - '.$email); if($this->errno!==250) { $this->errorAddr .= "Bad Email address : <b>".$email."</b> !<br />\n"; } else { $this->couldSend = true; } } } /** * 写邮件准备指令 */ protected function dataCommand() { $this->smtpWrite('data'); $this->smtpInfo('Input command',354); return true; } /** * 是否需要回执 */ public function needReturnReceipt($bool=false) { $this->returnReceipt = $bool; } /** * 是否开启字符串64位编码 */ public function ifBaseChar($bool=true) { $this->ifBaseChar = $bool; } /** * 设置邮优先级 */ public function setLevel($level='n') { $this->priority = $level; } /** * 是否支持HTML * * @param bool $bool */ public function supportHTML($bool=true) { $this->HTMLsupport = $bool; } /** * 设置字符集编码 * * @param str $char */ public function setChar($char='utf-8') { $this->charset = $char; } /** * 转换字符 * * @param str $Char * @return str */ protected function baseChar($Char) { if($this->ifBaseChar===true) { return '=?'.$this->charset.'?B?'.base64_encode($Char).'?='; } else { return $Char; } } /** * 写信件 */ protected function writeMail() { //当前时间 $time = date('D, j M Y G:i:s'); //分隔符 $cutter = uniqid('-=NextMailPart'); //邮件优先级 $pri = array('h'=>1,'n'=>3,'l'=>5); //发件人信息 $fromInfo = '"'.$this->baseChar($this->sender).'" <'.$this->from.'>'; $header.= 'From: '.$fromInfo.$this->CRLF; //普通发送 if($this->toStr) $header.= 'To: '.$this->toStr.$this->CRLF; //抄送 if($this->ccStr) $header.= 'Cc: '.$this->ccStr.$this->CRLF; //发送日期 $header.= "Date: $time +0800{$this->CRLF}"; //邮件主题 $header.= "Subject: ".$this->baseChar($this->subject).$this->CRLF; //邮件优先级 $header.= "X-Priority: {$pri[$this->priority]}{$this->CRLF}"; //是否需要回执 if($this->returnReceipt) $header.= "Disposition-Notification-To: ".$fromInfo.$this->CRLF; //MIME 版本 $header.= "MIME-Version: 1.0".$this->CRLF; //主题内容附件等的切割 $header.= 'Content-Type: Multipart/Mixed; Boundary="'.$cutter.'"'.$this->CRLF.$this->CRLF; $cutter = '--'.$cutter; $header.= $cutter.$this->CRLF; if(!$this->HTMLsupport) { $header.= "Content-Type: text/plain;charset=".$this->charset.";{$this->CRLF}"; } else { $header.= "Content-Type: text/html;charset=".$this->charset.";{$this->CRLF}"; } $mail = $header."{$this->CRLF}".$this->content."{$this->CRLF}"; if(!empty($this->attachment)) { foreach($this->attachment as $attachment) { $mail .= $cutter.$this->CRLF.$attachment; } unset($this->attachment); } $mail .= $cutter.'--'; $mail .= $this->CRLF.'.'; // die('<PRE>'.$mail.'</PRE>'); $this->smtpWrite($mail); $this->smtpInfo('Make mail !',250); return true; } /** * 添加附件 */ public function addAttachment($filename) { if(!file_exists($filename)) { $this->throwInfo('Add attachment !',$filename.' does not exist !',500); } else { $basename = basename($filename); } $headers .= 'Content-Type: '.$this->attachmentMime($basename).';'.$this->CRLF; $headers .= 'Content-Transfer-Encoding: base64'.$this->CRLF; $headers .= 'Content-Disposition: attachment;filename="'.$basename.'"'.$this->CRLF.$this->CRLF; $file = $this->attachmentEncode($filename); $this->attachment[] = $headers.$file; } /** * 返回附件Mime名 */ protected function attachmentMime($filename) { $mime = array( 'php'=>'text/plain', 'txt'=>'text/plain', 'asc'=>'text/plain', 'html'=>'text/plain', 'htm'=>'text/plain', 'js'=>'text/plain', 'css'=>'text/plain', 'asp'=>'text/plain', 'java'=>'text/plain', 'xml'=>'text/plain', 'xsl'=>'text/plain', 'wml'=>'text/plain', 'wmls'=>'text/plain', 'doc'=>'application/msword', 'xls'=>'application/vnd.ms-excel', 'ppt'=>'application/vnd.ms-powerpoint', 'pdf'=>'application/pdf', 'rar'=>'application/rar', 'zip'=>'application/zip', 'tar'=>'application/x-tar', 'gtar'=>'application/x-gtar', 'gz'=>'application/x-gzip', 'mid'=>'audio/midi', 'midi'=>'audio/midi', 'mp3'=>'audio/mpeg', 'ram'=>'audio/x-pn-realaudio', 'ra'=>'audio/x-pn-realaudio', 'rm'=>'application/vnd.rn-realmedia', 'rmvb'=>'application/vnd.rn-realmedia', 'wav'=>'audio/x-wav', 'bmp'=>'image/bmp', 'gif'=>'image/gif', 'jpg'=>'image/jpeg', 'jpeg'=>'image/jpeg', 'jpe'=>'image/jpeg', 'png'=>'image/png', 'ico'=>'image/x-icon', 'avi'=>'video/x-msvideo' ); $filename = explode('.',$filename); $extname = strtolower($filename[count($filename)-1]); if(empty($mime[$extname])) { return 'application/octet-stream'; } else { return $mime[$extname]; } } /** * 对附件进行64位编码 - 发送附件必须 */ protected function attachmentEncode($filename) { $handle = fopen($filename,'r+'); $fContent = fread($handle,filesize($filename)); fclose($handle); return chunk_split(base64_encode($fContent)); } /** * 从服务器读取smtp信息 * * @param str $step */ protected function smtpInfoBase($step) { if($this->fp != null) { $content = fgets($this->fp, 200); if($this->debug) echo '[<b>PHBMail Trace</b>] - (', date('H:i:'), date('s')+round(microtime(),4), ')<br />[Step]: ', $step, '<br /> [Response]: ', $content, "<br /><br />\n"; $this->makeInfo($step,substr($content,4,200),intval(substr($content,0,3))); } } protected function smtpInfo($step,$correctCode) { $this->smtpInfoBase($step); if($this->errno!==$correctCode) $this->throwE(); } protected function smtpWrite($content) { if($this->debug) echo '[Send] : ',htmlspecialchars($content),"<br />\n"; if($this->fp != null) { fwrite($this->fp,$content.$this->CRLF); } } /** * 生成错误报告 * * @param str $step * @param str $error * @param int $errno */ protected function makeInfo($step,$error,$errno) { $this->errno = $errno; $this->error = $error; $this->step = $step; } /** * PHBMail 抛出异常 * */ protected function throwE() { $this->disconnect(); //throw new PHBMailException($this->step,$this->error,$this->errno); } /** * 直接给出信息抛出 * * @param str $step * @param str $error * @param int $errno */ protected function throwInfo($step,$error,$errno) { $this->makeInfo($step,$error,$errno); $this->throwE($step,$error,$errno); } }